home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / ABUSESRC.ZIP / AbuseSrc / imlib / port / mac / video.c < prev   
Encoding:
C/C++ Source or Header  |  1996-04-11  |  13.9 KB  |  566 lines

  1. #include <QDOffscreen.h>
  2. #include <Palettes.h>
  3. #include <Displays.h>
  4. #include <Video.h>
  5. #include <Menus.h>
  6.  
  7. #include "video.hpp"
  8.  
  9. #include "filter.hpp"
  10. #include "globals.hpp"
  11. #include "system.h"
  12. #include "dos.h"
  13. #include "macs.hpp"
  14. #include "bitmap.h"
  15. #include "image.hpp"
  16. #include "jmalloc.hpp"
  17. #include <GUSI.h>
  18.  
  19. #include "RequestVideo.h"
  20.  
  21. // Resource id for crack window
  22. #define     WIND_CRACK     1000
  23.  
  24. #define PAL_DIRECT    // direct palette routines - yes!
  25. #define VIDEO_DIRECT  // direct video routines - yes!
  26.  
  27. unsigned char current_background;
  28. extern unsigned int xres,yres;
  29.  
  30. // Some number for jollies
  31. int vmode;
  32. image *screen;
  33.  
  34. Rect Bounds;
  35. CWindowPtr mainwin,backwin;
  36. CTabHandle MacCT,saved_pal;
  37. #ifndef PAL_DIRECT
  38. PaletteHandle MacPal;
  39. #endif
  40. int PixMult;
  41.  
  42. // Menu Globals
  43. short OldMBarHeight = 0;
  44. RgnHandle OldVisRgn = 0;
  45.  
  46. // DM stuff
  47. VideoRequestRec requestRec;
  48. VideoRequestRec originalRec;
  49. short        currentDepth;
  50. short        currentHorizontal;
  51. short        currentVertical;
  52.  
  53. // Direct Video globals
  54. GDHandle gd;
  55. short gVideoRowBytes;
  56. char *gVideoMem;
  57. Rect *gRect;
  58.  
  59. #ifdef VIDEO_DIRECT
  60. void (*SpeedCopyBits)(image *im, int sx1,int sy1, int sx2,int sy2, int dx,int dy);
  61. void SpeedCopyBits1(image *im, int sx1,int sy1, int sx2,int sy2, int dx,int dy);
  62. void SpeedCopyBits2(image *im, int sx1,int sy1, int sx2,int sy2, int dx,int dy);
  63. #endif
  64.  
  65. struct DisplayModeRequest
  66. {
  67.     // Returned values
  68.     unsigned short csMode;
  69.     unsigned long csData;
  70.  
  71.     // Provided values
  72.     long DesiredWidth;
  73.     long DesiredHeight;
  74.     long DesiredDepth;
  75. };
  76.  
  77. pascal void DisplayModeCallback(void* userData, DMListIndexType,
  78.     DMDisplayModeListEntryPtr pModeInfo)
  79. {
  80.     DisplayModeRequest *pRequest = (DisplayModeRequest*)userData;
  81.  
  82.     // Get timing info and make sure this is an OK display mode
  83.     VDTimingInfoRec TimingInfo = *(pModeInfo->displayModeTimingInfo);
  84.     if (TimingInfo.csTimingFlags & 1<<kModeValid)
  85.     {
  86.         // How many modes are being enumerated here?
  87.         unsigned long DepthCount =
  88.             pModeInfo->displayModeDepthBlockInfo->depthBlockCount;
  89.  
  90.         // Filter through each of the modes provided here
  91.         VDSwitchInfoRec *pSwitchInfo;
  92.         VPBlock *pVPBlockInfo;
  93.         for (short Count = 0; Count < DepthCount; ++Count)
  94.         {
  95.             // This provides the csMode and csData information
  96.             pSwitchInfo =
  97.                 pModeInfo->displayModeDepthBlockInfo->
  98.                 depthVPBlock[Count].depthSwitchInfo;
  99.  
  100.             // This tells us the resolution and pixel depth
  101.             pVPBlockInfo =
  102.                 pModeInfo->displayModeDepthBlockInfo->
  103.                 depthVPBlock[Count].depthVPBlock;
  104.  
  105.             if (pVPBlockInfo->vpPixelSize == pRequest->DesiredDepth &&
  106.                 pVPBlockInfo->vpBounds.right == pRequest->DesiredWidth &&
  107.                 pVPBlockInfo->vpBounds.bottom == pRequest->DesiredHeight)
  108.             {
  109.                 // Found a mode that matches the request!
  110.                 pRequest->csMode = pSwitchInfo->csMode;
  111.                 pRequest->csData = pSwitchInfo->csData;
  112.             }
  113.         }
  114.     }
  115. }
  116.  
  117. class CMacStartup {
  118. public:
  119.     CMacStartup()
  120.     {
  121.         // Initialize mac toolboxes
  122.         InitGraf(&qd.thePort);
  123.     InitFonts();
  124.     FlushEvents(everyEvent - osMask - diskMask, 0);
  125.     InitWindows();
  126.     InitMenus();
  127. //    TEInit();
  128.     InitDialogs(0L);
  129.     InitCursor();
  130.  
  131.         GUSIDefaultSetup();
  132.  
  133.     MaxApplZone();
  134.     MoreMasters();
  135.  
  136.         requestRec.screenDevice = nil;                    // find any screen
  137.         requestRec.reqBitDepth = 8;                            // bit depth request
  138.         requestRec.reqHorizontal = 640;                    // H request
  139.         requestRec.reqVertical = 480;                        // V request
  140.         requestRec.displayMode = nil;                        // must init to nil
  141.         requestRec.depthMode = nil;                            // must init to nil
  142.         requestRec.requestFlags = 1<<kAllValidModesBit;                        
  143.                                                                                         // give me the HxV over bit depth, and only safe video modes
  144.  
  145.         // make the request and set it if we have one....
  146.         RVRequestVideoSetting(&requestRec);
  147.  
  148.         if (requestRec.screenDevice == nil)        // make sure we found a device...possible if there are no "safe" video modes
  149.         {
  150.             fprintf(stderr,"Can't get current video mode\n");
  151.             exit(1);
  152.         }
  153.  
  154.         // Get current setting
  155.         originalRec.screenDevice = requestRec.screenDevice;        // this screen
  156.         RVGetCurrentVideoSetting(&originalRec);
  157.         
  158.         RVSetVideoRequest (&requestRec);
  159. //        if (noErr != RVConfirmVideoRequest (&requestRec))
  160. //            RVSetVideoRequest (&originalRec);
  161.         
  162.         PixMapHandle PMH;
  163.  
  164.         gd = requestRec.screenDevice;
  165.         PMH = (*gd)->gdPMap;
  166.         LockPixels(PMH);
  167.         gVideoRowBytes = (*PMH)->rowBytes & 0x3FFF;
  168.         gVideoMem = GetPixBaseAddr(PMH);
  169.         gRect = &(*gd)->gdRect;
  170.  
  171. #if 0
  172.  
  173.         for (int y=gRect->top; y<gRect->bottom; y++)
  174.             for (int x=gRect->left; x<gRect->right; x++)
  175.                 *(gVideoMem + (y*gVideoRowBytes+x)) = 0;
  176. #endif
  177.  
  178.         // set color table for 8 bit mode
  179.         
  180. #ifdef PAL_DIRECT
  181.         MacCT = (**((**gd).gdPMap)).pmTable;
  182. #else
  183.         MacCT = GetCTable(8);
  184.         MacPal = NewPalette(256,nil,pmTolerant,0);
  185.         (**MacCT).ctSeed = GetCTSeed();
  186. #endif
  187.         
  188.         PixMult = 1;
  189.     }
  190.     
  191.     ~CMacStartup()
  192.     {
  193.         FlushEvents(everyEvent, 0);
  194.         RVSetVideoRequest (&originalRec);
  195.         RVSetVideoAsScreenPrefs ();
  196.     }
  197. } MacStartup;
  198.  
  199. int get_vmode()
  200.     return vmode; 
  201. }
  202.  
  203. void image::make_page(short width, short height, unsigned char *page_buffer)
  204. //  creates memory that will be touched externally, for routines to copy to
  205. //  something will copy this memory to video memory
  206. {
  207.   if (special && !special->static_mem)
  208.   {
  209. #ifdef VIDEO_DIRECT
  210.     data=(unsigned char *)jmalloc(width*height,"image::direct_data");
  211. #else
  212.         GWorldPtr gw;
  213.         PixMapHandle pixmaph;
  214.         QDErr err;
  215.         Rect r;
  216.  
  217.       r.left = 0;
  218.       r.top = 0;
  219.       r.right = width;
  220.       r.bottom = height;
  221.       // use mac image, but set
  222.         err = NewGWorld( &gw, 8, &r, MacCT, nil, 0 );
  223.       special->extended_descriptor = gw;
  224.         pixmaph = GetGWorldPixMap(gw);
  225.         HLockHi((Handle)pixmaph);
  226.         LockPixels(pixmaph);
  227.       data = (unsigned char *)GetPixBaseAddr(pixmaph);
  228.       (**pixmaph).pmTable = MacCT;
  229.       
  230.       // yikes! hack the row bytes
  231.       (**pixmaph).rowBytes = 0x8000 | width;
  232.       w = (**pixmaph).rowBytes & 0x3fffl;
  233.       h = height;
  234.  #endif
  235.   }
  236.   else
  237.   {
  238.     if (!page_buffer)
  239.         // no preallocated image, so allocate some
  240.       data=(unsigned char *)jmalloc(width*height,"image::data");
  241.     else
  242.         // we want to use a preallocated image as this image's memory
  243.         data=page_buffer;
  244.   }
  245.  
  246.   if (special)
  247.       // set clipping area
  248.     special->resize(width,height);
  249. }
  250.  
  251. void image::delete_page()
  252. //  frees page memory
  253. {
  254.     if (special && !special->static_mem) {
  255. #ifdef VIDEO_DIRECT
  256.         jfree(data);
  257. #else
  258.         GWorldPtr gw;
  259.     
  260.         gw = (GWorldPtr)special->extended_descriptor;
  261.         
  262.         if (gw)
  263.             DisposeGWorld(gw);
  264. #endif
  265.         special->extended_descriptor = 0;
  266.     }
  267.     else if (!special)
  268.         jfree(data);
  269. }
  270.  
  271. void HideMenu()
  272. {
  273.     RgnHandle DesktopRgn;
  274.  
  275.     if (OldMBarHeight == 0)
  276.     {
  277.         // Get and copy the current gray region
  278.         DesktopRgn = LMGetGrayRgn();
  279.         OldVisRgn = NewRgn();
  280.         CopyRgn(DesktopRgn, OldVisRgn);
  281.         
  282.         // Fudge the menu bar height
  283.         OldMBarHeight = GetMBarHeight();
  284.         LMSetMBarHeight(0);
  285.  
  286.         // Turn the gray into the old gray region plus the menu bar region
  287.         Rect MenuRect;
  288.         MenuRect.left = 0;
  289.         MenuRect.top = 0;
  290.         MenuRect.right = qd.screenBits.bounds.right;
  291.         MenuRect.bottom = OldMBarHeight;
  292.         RgnHandle MenuRgn = NewRgn();
  293.         RectRgn(MenuRgn, &MenuRect);
  294.  
  295.         UnionRgn(OldVisRgn, MenuRgn, DesktopRgn);
  296.         DisposeRgn(MenuRgn);
  297.     }
  298. }
  299.  
  300. void RestoreMenu()
  301. {
  302.     if (OldMBarHeight && OldVisRgn)
  303.     {
  304.         // Restore the menu bar height
  305.         LMSetMBarHeight(OldMBarHeight);
  306.         OldMBarHeight = 0;
  307.  
  308.         // Restore the old desktop region
  309.         CopyRgn(OldVisRgn, LMGetGrayRgn());
  310.         DisposeRgn(OldVisRgn);
  311.         OldVisRgn = 0;
  312.         
  313.         // Redraw the menu bar
  314.         HiliteMenu(0);
  315.         DrawMenuBar();
  316.     }
  317. }
  318.  
  319. void set_mode(int mode, int argc, char **argv)
  320. {
  321.     Rect CurBounds;
  322.     GrafPtr savePort;
  323.  
  324. #ifdef VIDEO_DIRECT
  325.   // select copy routine
  326.   switch (PixMult)
  327.   {
  328.       case 1:  SpeedCopyBits = &SpeedCopyBits1; break;
  329.       case 2:  SpeedCopyBits = &SpeedCopyBits2; break;
  330.       default:
  331.           fprintf(stderr,"Aiiieee!  Can't set direct video copier.. it's gonna blow!\n");
  332.           break;
  333.   }
  334. #endif
  335.  
  336.     HideMenu();    
  337.  
  338.     Bounds = *gRect;
  339.  
  340.     backwin = (CWindowPtr)NewCWindow(nil, &Bounds, "\p", TRUE, 2, (WindowPtr)-1L, FALSE, 0);
  341.  
  342.     Bounds.left = (gRect->left+gRect->right)/2 - xres/2 * PixMult;
  343.     Bounds.right = (gRect->left+gRect->right)/2 + xres/2 * PixMult;
  344.     Bounds.top = (gRect->top+gRect->bottom)/2 - yres/2 * PixMult;
  345.     Bounds.bottom = (gRect->top+gRect->bottom)/2 + yres/2 * PixMult;
  346.     mainwin = (CWindowPtr)NewCWindow(nil, &Bounds, "\p", TRUE, 2, (WindowPtr)-1L, FALSE, 0);
  347.     SetGWorld((GWorldPtr)mainwin,gd);
  348.     CurBounds = mainwin->portRect;
  349.  
  350.     xres = (Bounds.right - Bounds.left)/PixMult;
  351.     yres = (Bounds.bottom - Bounds.top)/PixMult;
  352.  
  353.     // save old palette
  354.     saved_pal = (**((**gd).gdPMap)).pmTable;
  355.     HandToHand((Handle*)&saved_pal);
  356.     
  357.     // erase cursor
  358.     ShieldCursor(&CurBounds,topLeft((**(mainwin->portPixMap)).bounds));
  359.  
  360.     // create screen memory
  361.   screen=new image(xres,yres,NULL,2);  
  362.  
  363.     // clear screen
  364.   screen->clear();
  365.   update_dirty(screen);
  366.   
  367. }
  368.  
  369. void close_graphics()
  370. {
  371.   delete screen;
  372.  
  373. #ifdef PAL_DIRECT
  374.     ColorSpec *spec,*spec2;
  375.     VDSetEntryRecord setEntriesRec;
  376.     Ptr                 csPtr;
  377.     QDErr            error;
  378.     RgnHandle junkRgn;
  379.  
  380.     spec = (**MacCT).ctTable;
  381.     spec2 = (**saved_pal).ctTable;
  382.     for (int i=0; i<(**MacCT).ctSize; i++)
  383.     {
  384.         spec[i].rgb.red = spec2[i].rgb.red;
  385.         spec[i].rgb.green = spec2[i].rgb.green;
  386.         spec[i].rgb.blue = spec2[i].rgb.blue;
  387.         spec[i].value = spec2[i].value;
  388.     }
  389.     setEntriesRec.csTable = (ColorSpec *)&(**MacCT).ctTable;
  390.     setEntriesRec.csStart = 0;
  391.     setEntriesRec.csCount = (**MacCT).ctSize;
  392.     csPtr = (Ptr) &setEntriesRec;
  393.     error = Control ((**gd).gdRefNum, cscSetEntries, (Ptr) &csPtr);
  394.     if (error)
  395.         fprintf(stderr,"aieee! palette problem!\n");
  396. #else
  397.     // restore palette
  398.     MacPal = NewPalette((**saved_pal).ctSize,saved_pal,pmTolerant,0);
  399.     NSetPalette((WindowPtr)mainwin,MacPal,pmAllUpdates);
  400.     ActivatePalette((WindowPtr)mainwin);
  401. #endif
  402.     // restore cursor
  403.     ShowCursor();
  404.  
  405.     CloseWindow((WindowPtr)mainwin);
  406.     CloseWindow((WindowPtr)backwin);
  407.     
  408.     RestoreMenu();
  409. }
  410.  
  411. #ifdef VIDEO_DIRECT
  412.  
  413. void SpeedCopyBits1(image *im, int sx1,int sy1, int sx2,int sy2, int dx,int dy)
  414. {
  415.     int x,y;
  416.     unsigned char *p,*q,*pp,*qq;
  417.     unsigned long srclen = im->width();
  418.     
  419.     p = (unsigned char *)im->scan_line(sy1) + sx1;
  420.     q = (unsigned char *)gVideoMem + gVideoRowBytes*(dy+Bounds.top) + (dx+Bounds.left);
  421.     for (y=sy1; y<=sy2; y++)
  422.     {
  423.         pp = p;
  424.         qq = q;
  425.         for (x=sx1; x<=sx2; x++)
  426.             *(qq++) = *(pp++);
  427.         p += srclen;
  428.         q += gVideoRowBytes;
  429.     }
  430. }
  431.  
  432. void SpeedCopyBits2(image *im, int sx1,int sy1, int sx2,int sy2, int dx,int dy)
  433. {
  434.     int x,y;
  435.     unsigned char *p,*pp;
  436.     unsigned short *q,*qq,*qq2,dat;
  437.     unsigned long srclen = im->width();
  438.     
  439.     p = (unsigned char *)im->scan_line(sy1) + sx1;
  440.     q = (unsigned short*)((unsigned char *)gVideoMem + 
  441.                                                 gVideoRowBytes*(dy*2+Bounds.top) + (dx*2+Bounds.left));
  442.     for (y=sy1; y<=sy2; y++)
  443.     {
  444.         pp = p;
  445.         qq = q;
  446.         qq2 = (unsigned short*)((unsigned char*)q + gVideoRowBytes);
  447.         for (x=sx1; x<=sx2; x++) {
  448.             dat = *(pp++);
  449.             dat |= dat<<8;
  450.             *(qq++) = dat;
  451.             *(qq2++) = dat;
  452.         }
  453.         p += srclen;
  454.         q += gVideoRowBytes;
  455.     }
  456. }
  457.  
  458. #endif
  459.  
  460. void update_dirty(image *im, int xoff, int yoff)
  461. // go through list of dirty rects & display
  462. {
  463.   int count;
  464.   dirty_rect *dr,*q;
  465.   image *Xim;
  466.   CHECK(im->special);  // make sure the image has the ablity to contain dirty areas
  467.   if (im->special->keep_dirt==0)
  468. //    put_image(im,xoff,yoff);
  469.         q = 0;
  470.   else
  471.   {
  472.     count=im->special->dirties.number_nodes();
  473.     if (!count) return;  // if nothing to update, return
  474.     dr= (dirty_rect *) (im->special->dirties.first());
  475.     while (count>0)
  476.     {
  477. #ifdef VIDEO_DIRECT
  478.             (*SpeedCopyBits)(im, dr->dx1,dr->dy1, dr->dx2,dr->dy2, 
  479.                                         xoff + dr->dx1, yoff + dr->dy1);
  480. #else
  481.           GWorldPtr gw;
  482.           Rect src,dst;
  483.  
  484.         gw = (GWorldPtr)im->special->extended_descriptor;
  485.  
  486.         dst.left = (xoff + dr->dx1)*PixMult;
  487.         dst.top = (yoff + dr->dy1)*PixMult;
  488.         dst.right = (xoff + dr->dx2 + 1)*PixMult;
  489.         dst.bottom = (yoff + dr->dy2 + 1)*PixMult;
  490.         src.left = dr->dx1;
  491.         src.top = dr->dy1;
  492.         src.right = dr->dx2 + 1;
  493.         src.bottom = dr->dy2 + 1;
  494.             CopyBits((BitMap *) (*(gw->portPixMap)),
  495.                     (BitMap*) (*(mainwin->portPixMap)), 
  496.                     &src,
  497.                     &dst,
  498.                     srcCopy, nil);
  499. //      put_part_image(win,im,xoff+dr->dx1,yoff+dr->dy1,dr->dx1,dr->dy1,dr->dx2,dr->dy2);     
  500. //      XDrawRectangle(display,mainwin,gc,xoff+dr->dx1,yoff+dr->dy1,
  501. //             xoff+dr->dx2-dr->dx1+1,yoff+dr->dy2-dr->dy1+1);
  502. #endif
  503.       q=dr;
  504.       dr=(dirty_rect *) (dr->next());
  505.       im->special->dirties.unlink((linked_node *)q);
  506.       delete q;
  507.       count--;
  508.     }
  509.   }
  510. //  XFlush(display);
  511. }
  512.  
  513. void fill_image(image *im, int x1, int y1, int x2, int y2);
  514. void clear_put_image(image *im, int x, int y);
  515.  
  516. void palette::load()
  517. {
  518. #ifdef PAL_DIRECT
  519.     ColorSpec *spec;
  520.     VDSetEntryRecord setEntriesRec;
  521.     Ptr                 csPtr;
  522.     QDErr            error;
  523.  
  524.     spec = (**MacCT).ctTable;
  525.     for (int i=0; i<(**MacCT).ctSize; i++)
  526.     {
  527.         spec[i].rgb.red = red(i) * 256;
  528.         spec[i].rgb.green = green(i) * 256;
  529.         spec[i].rgb.blue = blue(i) * 256;
  530.         spec[i].value = i;
  531.     }
  532.     setEntriesRec.csTable = (ColorSpec *)&(**MacCT).ctTable;
  533.     setEntriesRec.csStart = 0;
  534.     setEntriesRec.csCount = (**MacCT).ctSize;
  535.     csPtr = (Ptr) &setEntriesRec;
  536.     error = Control ((**gd).gdRefNum, cscSetEntries, (Ptr) &csPtr);
  537.     if (error)
  538.         fprintf(stderr,"aieee! palette problem!\n");
  539. #else
  540.     ColorSpec *spec;
  541.     spec = (**MacCT).ctTable;
  542.     for (int i=0; i<pal_size(); i++)
  543.     {
  544.         spec[i].rgb.red = red(i) * 256;
  545.         spec[i].rgb.green = green(i) * 256;
  546.         spec[i].rgb.blue = blue(i) * 256;
  547.         spec[i].value = i;
  548.     }
  549. //    (**MacCT).ctSeed = GetCTSeed();
  550.     CTab2Palette(MacCT,MacPal,pmTolerant,0);
  551.     NSetPalette((WindowPtr)mainwin,MacPal,pmAllUpdates);
  552. //        HLockHi((Handle)mainwin->portPixMap);
  553. //        LockPixels(mainwin->portPixMap);
  554. //    (**mainwin->portPixMap).pmTable = MacCT;
  555.     ActivatePalette((WindowPtr)mainwin);
  556. #endif
  557. }
  558.  
  559. void palette::load_nice()
  560. {
  561.     // adapt palette to system's
  562.     load();
  563. }
  564.  
  565.